package com.abigdreamer.util;
/**   
 * 
 * @author Darkness
 * @date 2013-2-6 下午07:43:09
 * @website http://www.abigdreamer.com 
 * @version V1.0   
 */

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @class com.conch.ark.framework.utility.StringUtil
 * 字符串工具类
 * 
 * @author Darkness
 * @date 2012-8-4 上午10:36:08
 * @version V1.0
 */
@SuppressWarnings("restriction")
public class StringUtil {
	
	private static Logger logger = Logger.getLogger(StringUtil.class);
	
	public static final String GlobalCharset = "UTF-8";
	
	public static final byte[] BOM = { -17, -69, -65 };

	public static final char[] HexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static final Pattern PTitle = Pattern.compile("<title>(.+?)</title>", 34);

	public static Pattern patternHtmlTag = Pattern.compile("<[^<>]+>", 32);

	public static final Pattern PLetterOrDigit = Pattern.compile("^\\w*$", 34);

	public static final Pattern PLetter = Pattern.compile("^[A-Za-z]*$", 34);

	public static final Pattern PDigit = Pattern.compile("^\\d*$", 34);

	private static Pattern chinesePattern = Pattern.compile("[^一-龥]+", 34);

	private static Pattern idPattern = Pattern.compile("[\\w\\s\\_\\.\\,]*", 34);

	/**
	 * 利用MD5进行加密
	 * 
	 * @param src
	 *            待加密的字符串
	 * @return 加密后的字节
	 * 
	 * @author Darkness
	 * @date 2012-8-4 下午1:27:13
	 * @version V1.0
	 */
	public static byte[] md5(String src) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] md = md5.digest(src.getBytes());
			return md;
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 利用MD5进行加密
	 * 
	 * @param src
	 *            待加密的字节
	 * @return 加密后的字节
	 * 
	 * @author Darkness
	 * @date 2012-8-4 下午1:29:48
	 * @version V1.0
	 */
	public static byte[] md5(byte[] src) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] md = md5.digest(src);
			return md;
		} catch (Exception e) {
		}
		return null;
	}

	public static String md5Hex(String src) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] md = md5.digest(src.getBytes());
			return hexEncode(md);
		} catch (Exception e) {
		}
		return null;
	}

	public static String sha1Hex(String src) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("SHA1");
			byte[] md = md5.digest(src.getBytes());
			return hexEncode(md);
		} catch (Exception e) {
		}
		return null;
	}

	public static String md5Base64(String str) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			return base64Encode(md5.digest(str.getBytes()));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String md5Base64FromHex(String md5str) {
		char[] cs = md5str.toCharArray();
		byte[] bs = new byte[16];
		for (int i = 0; i < bs.length; i++) {
			char c1 = cs[(i * 2)];
			char c2 = cs[(i * 2 + 1)];
			byte m1 = 0;
			byte m2 = 0;
			for (byte k = 0; k < 16; k = (byte) (k + 1)) {
				if (HexDigits[k] == c1) {
					m1 = k;
				}
				if (HexDigits[k] == c2) {
					m2 = k;
				}
			}
			bs[i] = (byte) (m1 << 4 | 0 + m2);
		}

		String newstr = base64Encode(bs);
		return newstr;
	}

	public static String md5HexFromBase64(String base64str) {
		return hexEncode(base64Decode(base64str));
	}

	/**
	 * 十六进制编码
	 * 
	 * @author Darkness
	 * @date 2012-8-4 下午11:04:24 
	 * @version V1.0
	 */
	public static String hexEncode(byte[] bs) {
		return new String(new Hex().encode(bs));
	}

	public static byte[] hexDecode(String str) {
		try {
			if (str.endsWith("\n")) {
				str = str.substring(0, str.length() - 1);
			}
			char[] cs = str.toCharArray();
			return Hex.decodeHex(cs);
		} catch (DecoderException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String byteToBin(byte[] bs) {
		char[] cs = new char[bs.length * 9];
		for (int i = 0; i < bs.length; i++) {
			byte b = bs[i];
			int j = i * 9;
			cs[j] = ((b >>> 7 & 0x1) == 1 ? 49 : '0');
			cs[(j + 1)] = ((b >>> 6 & 0x1) == 1 ? 49 : '0');
			cs[(j + 2)] = ((b >>> 5 & 0x1) == 1 ? 49 : '0');
			cs[(j + 3)] = ((b >>> 4 & 0x1) == 1 ? 49 : '0');
			cs[(j + 4)] = ((b >>> 3 & 0x1) == 1 ? 49 : '0');
			cs[(j + 5)] = ((b >>> 2 & 0x1) == 1 ? 49 : '0');
			cs[(j + 6)] = ((b >>> 1 & 0x1) == 1 ? 49 : '0');
			cs[(j + 7)] = ((b & 0x1) == 1 ? 49 : '0');
			cs[(j + 8)] = ',';
		}
		return new String(cs);
	}

	public static String byteArrayToHexString(byte[] b) {
		StringBuilder resultSb = new StringBuilder();
		for (int i = 0; i < b.length; i++) {
			resultSb.append(byteToHexString(b[i]));
			resultSb.append(" ");
		}
		return resultSb.toString();
	}

	private static String byteToHexString(byte b) {
		int n = b;
		if (n < 0) {
			n += 256;
		}
		int d1 = n / 16;
		int d2 = n % 16;
		return (HexDigits[d1] + HexDigits[d2]) + "";
	}

	public static boolean isUTF8(byte[] bs) {
		if (hexEncode(ArrayUtils.subarray(bs, 0, 3)).equals("efbbbf")) {
			return true;
		}
		int encodingBytesCount = 0;
		for (int i = 0; i < bs.length; i++) {
			byte c = bs[i];
			if (encodingBytesCount == 0) {
				if ((c & 0x80) == 0) {
					continue;
				}
				if ((c & 0xC0) == 192) {
					encodingBytesCount = 1;
					c = (byte) (c << 2);

					while ((c & 0x80) == 128) {
						c = (byte) (c << 1);
						encodingBytesCount++;
					}
				} else {
					return false;
				}

			} else if ((c & 0xC0) == 128) {
				encodingBytesCount--;
			} else {
				return false;
			}

		}

		return encodingBytesCount == 0;
	}

	public static String base64Encode(byte[] b) {
		if (b == null) {
			return null;
		}
		return new BASE64Encoder().encode(b);
	}

	public static byte[] base64Decode(String s) {
		if (s != null) {
			BASE64Decoder decoder = new BASE64Decoder();
			try {
				return decoder.decodeBuffer(s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static String javaEncode(String txt) {
		if ((txt == null) || (txt.length() == 0)) {
			return txt;
		}
		txt = replaceEx(txt, "\\", "\\\\");
		txt = replaceEx(txt, "\r\n", "\n");
		txt = replaceEx(txt, "\r", "\\r");
		txt = replaceEx(txt, "\t", "\\t");
		txt = replaceEx(txt, "\n", "\\n");
		txt = replaceEx(txt, "\"", "\\\"");
		txt = replaceEx(txt, "'", "\\'");
		return txt;
	}

	public static String javaDecode(String txt) {
		if ((txt == null) || (txt.length() == 0)) {
			return txt;
		}
		StringBuilder sb = new StringBuilder();
		int lastIndex = 0;
		while (true) {
			int index = txt.indexOf("\\", lastIndex);
			if (index < 0) {
				break;
			}
			sb.append(txt.substring(lastIndex, index));
			if (index < txt.length() - 1) {
				char c = txt.charAt(index + 1);
				if (c == 'n')
					sb.append("\n");
				else if (c == 'r')
					sb.append("\r");
				else if (c == 't')
					sb.append("\t");
				else if (c == '\'')
					sb.append("'");
				else if (c == '"')
					sb.append("\"");
				else if (c == '\\') {
					sb.append("\\");
				}
				lastIndex = index + 2;
				continue;
			}
			sb.append(txt.substring(index, index + 1));

			lastIndex = index + 1;
		}
		sb.append(txt.substring(lastIndex));
		return sb.toString();
	}

	/**
	 * 根据分隔符拆分字符串，如：StringUtil.splitEx(text, "\n");
	 * @param str 需要拆分的字符串
	 * @param spliter 分隔符
	 * @return 拆分后的字符串数组
	 * @author Darkness
	 * @date 2012-8-5 下午5:01:48 
	 * @version V1.0
	 */
	public static String[] splitEx(String str, String spliter) {
		char escapeChar = '\\';
		if (spliter.equals("\\")) {
			escapeChar = '&';
		}
		return splitEx(str, spliter, escapeChar);
	}

	public static String[] splitEx(String str, String spliter, char escapeChar) {
		if (str == null) {
			return null;
		}
		if ((spliter == null) || (spliter.equals("")) || (str.length() < spliter.length())) {
			String[] t = { str };
			return t;
		}
		ArrayList list = new ArrayList();
		char[] cs = str.toCharArray();
		char[] ss = spliter.toCharArray();
		int length = spliter.length();
		int lastIndex = 0;
		for (int i = 0; i <= str.length() - length;) {
			boolean notSuit = false;
			for (int j = 0; j < length; j++) {
				if (cs[(i + j)] != ss[j]) {
					notSuit = true;
					break;
				}
			}
			if (!notSuit) {
				list.add(str.substring(lastIndex, i));
				i += length;
				lastIndex = i;
			} else {
				i++;
			}
		}
		if (lastIndex <= str.length()) {
			list.add(str.substring(lastIndex, str.length()));
		}
		ArrayList r = new ArrayList(list.size());
		for (int i = 0; i < list.size(); i++) {
			String a = (String) list.get(i);
			if ((a.length() > 0) && (a.charAt(a.length() - 1) == escapeChar)) {
				r.add(a.substring(0, a.length() - 1) + spliter + (i == list.size() - 1 ? "" : (String) list.get(i + 1)));
				i++;
			} else {
				r.add(a);
			}
		}
		String[] t = new String[r.size()];
		return (String[]) r.toArray(t);
	}

	/**
	 * 将字符串中的指定字符替换成其他字符，非正则替换，如：
	 * 
	 * 非正则替换：
	 * String result1 = StringUtil.replaceEx("com.conch.ark.framework.utility.StringUtil", ".", "/");
	 * __>com/conch/framework/utility/StringUtil
	 * 
	 * 正则替换：
	 * String result1 = "com.conch.ark.framework.utility.StringUtil".replaceAll(".", "/");
	 * __>//////////////////////////////////////
	 * 
	 * @param str 字符串
	 * @param subStr 需要替换的字符
	 * @param reStr 替换字符
	 * @return 替换后的字符串
	 * @author Darkness
	 * @date 2012-8-5 下午5:20:43 
	 * @version V1.0
	 */
	public static String replaceEx(String str, String subStr, String reStr) {
		if (str == null) {
			return null;
		}
		if ((subStr == null) || (subStr.equals("")) || (subStr.length() > str.length()) || (reStr == null)) {
			return str;
		}
		StringBuilder sb = new StringBuilder();
		int lastIndex = 0;
		while (true) {
			int index = str.indexOf(subStr, lastIndex);
			if (index < 0) {
				break;
			}
			sb.append(str.substring(lastIndex, index));
			sb.append(reStr);

			lastIndex = index + subStr.length();
		}
		sb.append(str.substring(lastIndex));
		return sb.toString();
	}

	public static String replaceAllIgnoreCase(String source, String oldstring, String newstring) {
		Pattern p = Pattern.compile(oldstring, 34);
		Matcher m = p.matcher(source);
		return m.replaceAll(newstring);
	}

	public static String urlEncode(String str) {
		return urlEncode(str, GlobalCharset);
	}

	public static String urlDecode(String str) {
		return urlDecode(str, GlobalCharset);
	}

	public static String urlEncode(String str, String charset) {
		try {
			return new URLCodec().encode(str, charset);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String urlDecode(String str, String charset) {
		try {
			return new URLCodec().decode(str, charset);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String htmlEncode(String txt) {
		return StringEscapeUtils.escapeHtml(txt);
	}

	public static String htmlDecode(String txt) {
		txt = replaceEx(txt, "&#8226;", "·");
		return StringEscapeUtils.unescapeHtml(txt);
	}

	public static String quotEncode(String txt) {
		if ((txt == null) || (txt.length() == 0)) {
			return txt;
		}
		txt = replaceEx(txt, "&", "&amp;");
		txt = replaceEx(txt, "\"", "&quot;");
		return txt;
	}

	public static String quotDecode(String txt) {
		if ((txt == null) || (txt.length() == 0)) {
			return txt;
		}
		txt = replaceEx(txt, "&quot;", "\"");
		txt = replaceEx(txt, "&amp;", "&");
		return txt;
	}

	public static String escape(String src) {
		StringBuilder sb = new StringBuilder();
		sb.ensureCapacity(src.length() * 6);
		for (int i = 0; i < src.length(); i++) {
			char j = src.charAt(i);
			if ((Character.isDigit(j)) || (Character.isLowerCase(j)) || (Character.isUpperCase(j))) {
				sb.append(j);
			} else if (j < 'Ā') {
				sb.append("%");
				if (j < '\020') {
					sb.append("0");
				}
				sb.append(Integer.toString(j, 16));
			} else {
				sb.append("%u");
				sb.append(Integer.toString(j, 16));
			}
		}
		return sb.toString();
	}

	public static String unescape(String src) {
		StringBuilder sb = new StringBuilder();
		sb.ensureCapacity(src.length());
		int lastPos = 0;
		int pos = 0;

		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					char ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
					sb.append(ch);
					lastPos = pos + 6;
				} else {
					char ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
					sb.append(ch);
					lastPos = pos + 3;
				}
			} else if (pos == -1) {
				sb.append(src.substring(lastPos));
				lastPos = src.length();
			} else {
				sb.append(src.substring(lastPos, pos));
				lastPos = pos;
			}
		}

		return sb.toString();
	}

	/**
	 * String str = "1";
	 * String result = StringUtil.leftPad(str, '0', 4);
	 *	
	 *	Assert.assertEquals("0001", result);
	 * 
	 * @author Darkness
	 * @date 2012-12-2 下午03:15:15 
	 * @version V1.0
	 */
	public static String leftPad(String srcString, char c, int length) {
		if (srcString == null) {
			srcString = "";
		}
		int tLen = srcString.length();

		if (tLen >= length)
			return srcString;
		int iMax = length - tLen;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < iMax; i++) {
			sb.append(c);
		}
		sb.append(srcString);
		return sb.toString();
	}

	public static String subString(String src, int length) {
		if (src == null) {
			return null;
		}
		int i = src.length();
		if (i > length) {
			return src.substring(0, length);
		}
		return src;
	}

	public static String subStringEx(String src, int length) {
		if (src == null) {
			return null;
		}
		int m = 0;
		boolean unixFlag = false;
		String osname = System.getProperty("os.name").toLowerCase();
		if ((osname.indexOf("sunos") > 0) || (osname.indexOf("solaris") > 0) || (osname.indexOf("aix") > 0) || ((osname.indexOf("windows") >= 0) && (osname.indexOf("7") > 0)))
			unixFlag = true;
		try {
			byte[] b = src.getBytes("Unicode");
			for (int i = 2; i < b.length; i += 2) {
				byte flag = b[(i + 1)];
				if (unixFlag) {
					flag = b[i];
				}
				if (flag == 0)
					m++;
				else {
					m += 2;
				}
				if (m > length)
					return src.substring(0, (i - 2) / 2);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException("String.getBytes(\"Unicode\") failed");
		}
		return src;
	}



	public static String rightPad(String srcString, char c, int length) {
		if (srcString == null) {
			srcString = "";
		}
		int tLen = srcString.length();

		if (tLen >= length)
			return srcString;
		int iMax = length - tLen;
		StringBuilder sb = new StringBuilder();
		sb.append(srcString);
		for (int i = 0; i < iMax; i++) {
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 去除字符串右边的' '、'\t'、'\r'字符
	 * @param src 字符串
	 * @return 去除右边' '、'\t'、'\r'后的字符串
	 * @author Darkness
	 * @date 2012-8-5 下午5:06:26 
	 * @version V1.0
	 */
	public static String rightTrim(String src) {
		if (src != null) {
			char[] chars = src.toCharArray();
			for (int i = chars.length - 1; i >= 0; i--) {
				if ((chars[i] != ' ') && (chars[i] != '\t') && (chars[i] != '\r')) {
					return src.substring(0, i + 1);
				}
			}
			return "";
		}
		return src;
	}

	public static void printStringWithAnyCharset(String str) {
		SortedMap<String, Charset> map = Charset.availableCharsets();
		for (String key1 : map.keySet()) {
			logger.info(key1);
			for (String key2 : map.keySet()) {
				System.out.print("\t");
				try {
					System.out.println("From " + key1 + " To " + key2 + ":" + new String(str.getBytes(key1.toString()), key2.toString()));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static String toSBC(String input) {
		char[] c = input.toCharArray();
		for (int i = 0; i < c.length; i++)
			if (c[i] == ' ') {
				c[i] = '　';
			} else {
				if (((c[i] > '@') && (c[i] < '[')) || ((c[i] > '`') && (c[i] < '{'))) {
					continue;
				}
				if (c[i] < '')
					c[i] = (char) (c[i] + 65248);
			}
		return new String(c);
	}

	public static String toNSBC(String input) {
		char[] c = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == ' ') {
				c[i] = '　';
			} else if (c[i] < '')
				c[i] = (char) (c[i] + 65248);
		}
		return new String(c);
	}

	public static String toDBC(String input) {
		char[] c = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == '　') {
				c[i] = ' ';
			} else if ((c[i] > 65280) && (c[i] < 65375))
				c[i] = (char) (c[i] - 65248);
		}
		return new String(c);
	}



	public static String getHtmlTitle(File f) {
		String html = FileUtil.readText(f);
		String title = getHtmlTitle(html);
		return title;
	}

	public static String getHtmlTitle(String html) {
		Matcher m = PTitle.matcher(html);
		if (m.find()) {
			return m.group(1).trim();
		}
		return null;
	}

	public static String clearHtmlTag(String html) {
		String text = patternHtmlTag.matcher(html).replaceAll("");
		if (isEmpty(text)) {
			return "";
		}
		text = htmlDecode(text);
		return text.replaceAll("[\\s　]{2,}", " ");
	}

	public static String htmlTagEncode(String str) {
		if (isEmpty(str))
			return str;
		while (true) {
			Matcher matcher = patternHtmlTag.matcher(str);
			if (!matcher.find())
				break;
			String content = matcher.group(0);
			str = matcher.replaceFirst(htmlEncode(content));
		}

		return str.replaceAll("[\\s　]{2,}", " ");
	}

	public static String capitalize(String str) {
		int strLen;
		if ((str == null) || ((strLen = str.length()) == 0))
			return str;
		return strLen + Character.toTitleCase(str.charAt(0)) + str.substring(1);
	}

	public static boolean isEmpty(String str) {
		return (str == null) || (str.length() == 0);
	}

	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	public static boolean isNull(String str) {
		return (isEmpty(str)) || ("null".equals(str));
	}

	public static boolean isNotNull(String str) {
		return (isNotEmpty(str)) && (!"null".equals(str));
	}

	public static final String noNull(String string, String defaultString) {
		return isEmpty(string) ? defaultString : string;
	}

	public static final String noNull(String string) {
		return noNull(string, "");
	}

	public static String join(Object[] arr) {
		return join(arr, ",");
	}

	public static String join(Object[][] arr) {
		return join(arr, "\n", ",");
	}

	public static String join(Object[] arr, String spliter) {
		if (arr == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			if (i != 0) {
				sb.append(spliter);
			}
			sb.append(arr[i]);
		}
		return sb.toString();
	}

	public static String join(Object[][] arr, String spliter1, String spliter2) {
		if (arr == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			if (i != 0) {
				sb.append(spliter2);
			}
			sb.append(join(arr[i], spliter2));
		}
		return sb.toString();
	}

	public static String join(List<?> list) {
		return join(list, ",");
	}

	public static String join(List<?> list, String spliter) {
		if (list == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			if (i != 0) {
				sb.append(spliter);
			}
			sb.append(list.get(i));
		}
		return sb.toString();
	}

	/**
	 * 查找字符串中存在被查找字符串的个数
	 * @param str 字符串
	 * @param findStr 查找的字符串
	 * @return 查找字符串在被查找字符串中出现的次数
	 * 
	 * @author Darkness
	 * @date 2012-8-5 下午6:30:38 
	 * @version V1.0
	 */
	public static int count(String str, String findStr) {
		int lastIndex = 0;
		int length = findStr.length();
		int count = 0;
		int start = 0;
		while ((start = str.indexOf(findStr, lastIndex)) >= 0) {
			lastIndex = start + length;
			count++;
		}
		return count;
	}

	public static boolean isLetterOrDigit(String str) {
		return PLetterOrDigit.matcher(str).find();
	}

	public static boolean isLetter(String str) {
		return PLetter.matcher(str).find();
	}

	public static boolean isDigit(String str) {
		if (isEmpty(str)) {
			return false;
		}
		return PDigit.matcher(str).find();
	}

	public static boolean containsChinese(String str) {
		return !chinesePattern.matcher(str).matches();
	}

	public static boolean checkID(String str) {
		if (isEmpty(str)) {
			return true;
		}

		return idPattern.matcher(str).matches();
	}



	public static String getURLExtName(String url) {
		if (isEmpty(url)) {
			return null;
		}
		int index1 = url.indexOf('?');
		if (index1 == -1) {
			index1 = url.length();
		}
		int index2 = url.lastIndexOf('.', index1);
		if (index2 == -1) {
			return null;
		}
		int index3 = url.indexOf('/', 8);
		if (index3 == -1) {
			return null;
		}
		String ext = url.substring(index2 + 1, index1);
		if (ext.matches("[^\\/\\\\]*")) {
			return ext;
		}
		return null;
	}

	public static String getURLFileName(String url) {
		if (isEmpty(url)) {
			return null;
		}
		int index1 = url.indexOf('?');
		if (index1 == -1) {
			index1 = url.length();
		}
		int index2 = url.lastIndexOf('/', index1);
		if ((index2 == -1) || (index2 < 8)) {
			return null;
		}
		String ext = url.substring(index2 + 1, index1);
		return ext;
	}




	public static String clearForXML(String str) {
		char[] cs = str.toCharArray();
		char[] ncs = new char[cs.length];
		int j = 0;
		for (int i = 0; i < cs.length; i++) {
			if (cs[i] > 65533)
				continue;
			if (cs[i] < ' ')
				if (((cs[i] != '\t' ? 1 : 0) & (cs[i] != '\n' ? 1 : 0) & (cs[i] != '\r' ? 1 : 0)) != 0) {
					continue;
				}
			ncs[(j++)] = cs[i];
		}
		ncs = ArrayUtils.subarray(ncs, 0, j);
		return new String(ncs);
	}


}
